package com.kang.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import com.kang.util.AuthFailResponse;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.*;

/**
 * IP拦截
 * 请求都有一个源头
 * 请求------>gateWay-------->service
 * 黑名单   BlackList
 * 白名单   WhitList
 * 根据数量来判断使用白名单还是黑名单
 * 一般具体的业务  使用黑名单;
 * 一般数据库 使用白名单
 */
@Component
public class IPCheckFilter implements GlobalFilter, Ordered {

    /**
     * 网关的性能比较高  不要再网关里面直接操作数据库
     * 后台系统多数操作数据库
     */
    public static final List<String> BLOCK_LIST = Arrays.asList("121.4.248.132","127.0.0.1","10.1.2.127");


    /**
     * 拿到IP
     * 校验Ip是否符合规范
     * 放行 / 拦截
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String ip = request.getHeaders().getHost().getHostString();
        //查询数据库  判断Ip是否存在黑名单里面 数据库的并发
        //只要能存数据的地方都叫数据库
        if (!BLOCK_LIST.contains(ip)) {
            return chain.filter(exchange);
        }
        //包含的话 拦截
        ServerHttpResponse response = exchange.getResponse();
        HttpHeaders headers = response.getHeaders();
        headers.set("content-type","application/json;charset=utf-8");
        DataBuffer wrap = AuthFailResponse.authFailResponse("438", "你是黑名单", response);
        return response.writeWith(Mono.just(wrap));

    }

    @Override
    public int getOrder() {
        return -1;
    }
}
